﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Web;
using System.IO;
using System.Xml.Serialization;
using System.Xml;
using System.Web.UI;

namespace ExtEasy
{
    /// <summary>
    /// Разные полезные методы
    /// </summary>
    public static class ExtUtils
    {
        public static string DateToRussianString(DateTime date)
        {
            return string.Format("{0:dd.MM.yyyy}", date);
        }

        public static DateTime ParseRussianDate(string str)
        {
            IFormatProvider culture = new CultureInfo("ru-RU", false);
            DateTime dt = DateTime.Now;
            DateTime.TryParse(str, culture, DateTimeStyles.None, out dt);
            if (dt == DateTime.MinValue) dt = DateTime.Now;
            return dt;
        }


        /// <summary>
        /// Объем файла из байт в приличную строку
        /// </summary>
        /// <param name="bytesize"></param>
        /// <returns></returns>
        public static string ConvertSize(long bytesize)
        {
            long size = bytesize;

            //try
            //{
            //    size = int.Parse(bytesize);
            //}
            //catch (Exception ex)
            //{
            //    string Message = ex.Message;
            //    return bytesize;
            //}
            string unitname = "";
            string bytesizestr = "";

            if (size < 1024)
            {
                //return ((Double)(Convert.ToDouble(size))).ToString() + " Байт";
                bytesizestr = ((Double)(Convert.ToDouble(size))).ToString();
                unitname = " Байт";
            }
            else
            {

                if ((1024 <= size) && (size < 1024 * 1024))
                {
                    //  return ((Double)(Convert.ToDouble(size) / 1024)).ToString() + " Кб";
                    bytesizestr = ((Double)(Convert.ToDouble(size) / 1024)).ToString();
                    unitname = " Кб";
                }
                else
                {

                    if ((1024 * 1024 <= size))
                    {
                        //  return ((Double)(Convert.ToDouble(size) / (1024 * 1024))).ToString() + " Мб";
                        bytesizestr = ((Double)(Convert.ToDouble(size) / (1024 * 1024))).ToString();
                        unitname = " Мб";
                    }
                    else
                    {
                        bytesizestr = bytesize.ToString();
                    }
                }
            }


            //if (bytesizestr.IndexOf(',')>0) bytesizestr=bytesizestr.Remove(bytesizestr.IndexOf(',')+2);
            return bytesizestr + unitname;

        }

        /// <summary>
        /// Полный URL-путь приложения с учетом всего
        /// </summary>
        /// <returns></returns>
        public static string GetAbsolutePath()
        {
            //HttpContext.Current.Request.ServerVariables["REMOTE_HOST"];

            string absoluteRoot = HttpContext.Current.Request.Url.Scheme + "://" + (string.IsNullOrEmpty(HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_HOST"])? HttpContext.Current.Request.ServerVariables["HTTP_HOST"] : HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_HOST"]);// HttpContext.Current.Request.Url.Host;

            if (HttpContext.Current.Request.Url.Port != 80)
                absoluteRoot += ":" + HttpContext.Current.Request.Url.Port.ToString();

            if (HttpContext.Current.Request.ApplicationPath.Length > 0)
                absoluteRoot += HttpContext.Current.Request.ApplicationPath;

            if (HttpContext.Current.Request.Url.Port == 80) absoluteRoot += "/";
            //    HttpContext.Current.Items.Add("absolute-root", absoluteRoot);

            if (!absoluteRoot.EndsWith("/")) absoluteRoot += "/";

            //if (absoluteRoot.EndsWith("/")) absoluteRoot = absoluteRoot.Substring(0, absoluteRoot.Length - 1);
            return absoluteRoot;// +HttpContext.Current.Response.ApplyAppPathModifier("~/");// HttpContext.Current.Items["absolute-root"] as string;
            
           // return HttpContext.Current.Response.ApplyAppPathModifier("~/");
            //absoluteRoot += HttpContext.Current.Response.ApplyAppPathModifier("~/");

            //if (s.EndsWith("/")) s = s.Substring(0, s.Length - 1);
            //return s;
            //Control c = new Control();
            //return c.ResolveClientUrl("~/");       
            //return ((Control)HttpContext.Current.CurrentHandler).ResolveClientUrl("~/");
           // HttpContext.Current.Request.Url.
        }


        public static double ParseRussianDouble(string s)
        {
            s = s.Replace(',', '.');
            IFormatProvider culture = new CultureInfo(CultureInfo.InvariantCulture.Name);
            double f = 0;
            double.TryParse(s, NumberStyles.Number, culture, out f);
            return f;
        }

        public static string DoubleToRussianString(double f)
        {
            // IFormatProvider culture = new CultureInfo(CultureInfo.InvariantCulture.Name);
            return f.ToString("#.##", CultureInfo.InvariantCulture).Replace('.', ',');
        }



        public static string ObjectToRussianString(object f)
        {
            return string.Format(CultureInfo.InvariantCulture, "{0:#.##}", f);
        }

        /// <summary>
        /// По названию параметра загружает его значение из query string. 
        /// В случае успешного выполнения операции возвращает true.
        /// </summary>
        /// <typeparam name="T">Тип считываемого параметра.</typeparam>
        /// <param name="paramname">Имя считываемого параметра.</param>
        /// <param name="value">Значение считываемого параметра.</param>
        /// <returns>Возвращает True если параметр существует в query string и его значение корректно преобразуется к типу T.</returns>
        public static bool ReadParam<T>(string paramname, out T value)
        {
            try
            {
                // value = default(T) ;
                if (string.IsNullOrEmpty(paramname)) throw new Exception("Param name is null or empty!");
                if (HttpContext.Current == null) throw new Exception("Param name is null or empty!");
                // return Int32.TryParse(HttpContext.Current.Request.Params[paramname], value);

                string paramValue = HttpContext.Current.Request.Params[paramname];
                if (paramValue == null) throw new Exception("Param name is null or empty!");

                value = (T)Convert.ChangeType(paramValue, typeof(T),CultureInfo.InvariantCulture);
                return true;
            }
            // catch (InvalidCastException)
            catch (Exception ex)
            {
                value = default(T);
                string msg = ex.Message;
                return false;
            }
        }


        /// <summary>
        /// Возвращает окончание слова 
        /// </summary>
        /// <param name="s1">окончание ед.ч. ("мероприятие")</param>
        /// <param name="s2">окончание мн.ч. ("мероприятия")</param>
        /// <param name="s3">окончание очень мн.ч. ("мероприятий")</param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string GetWordEnds(string s1, string s2, string s3, int count)
        {
            if (Convert.ToInt32(count / 10) % 10 == 1)
            {
                return s3;
            }
            else
            {
                if (count % 10 == 1)
                {
                    return  s1;
                }
                else
                {
                    if ((count % 10 == 2) || (count % 10 == 3) || (count % 10 == 4))
                    {
                        return s2;
                    }
                    else
                    {
                        return s3;
                    }
                }
            }
        }


        public static string GetMessageScript(string divid, string message,string color)
        {
            return "$('#" + divid + "').css({visibility:'visible'}).css({display:'inline'}).css({color:'" + color + "'}).html('" + message + "').animate({opacity: 'hide'},{duration:3000});";
        }


        /// <summary>
        /// Генерит превьюшку заданной ширины и вычисленной высоты
        /// </summary>
        /// <param name="stm">Поток картинки</param>
        /// <param name="Ws">Ширина</param>
        /// <returns></returns>
        public static byte[] GetThumbnail(Stream stm, int Ws)
        {
            System.Drawing.Image image = null;
            try
            {
                image = System.Drawing.Image.FromStream(stm);
            }
            catch 
            {
                return new byte[0];
            }
            //int Ws = 150;

            System.Drawing.Image thumbnailImage = image.GetThumbnailImage(Ws, image.Size.Height * Ws / image.Size.Width,/* new System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback)*/null, IntPtr.Zero);
            MemoryStream imageStream = new MemoryStream();
            thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] imageContent = new Byte[imageStream.Length];

            // rewind the memory stream
            imageStream.Position = 0;

            // load the byte array with the image
            imageStream.Read(imageContent, 0, (int)imageStream.Length);

            // return byte array to caller with image type
            //Response.ContentType = "image/jpeg";
            //Response.BinaryWrite(imageContent);
            return imageContent;
        }


        /// <summary>
        /// Получает MD5 по паролю
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string GetMD5Hash(string input)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] bs = System.Text.Encoding.UTF8.GetBytes(input);
            bs = x.ComputeHash(bs);
            System.Text.StringBuilder s = new System.Text.StringBuilder();
            foreach (byte b in bs)
            {
                s.Append(b.ToString("x2").ToLower());
            }
            string password = s.ToString();
            return password;
        }


       /* #region Serialization
        public static string SerializeClass(object obj)
        {
            using (StringWriter writer = new StringWriter())
            {
                System.Type type = obj.GetType();
                XmlSerializer xs = new XmlSerializer(type);
                xs.Serialize(writer, obj);
                return writer.ToString();
            }           
        }

        public static object DeserializeClass(string xml, System.Type type)
        {
            XmlSerializer xs = new XmlSerializer(type);            
            StringReader read = new StringReader(xml);
            XmlReader reader = new XmlTextReader(read);
            return xs.Deserialize(reader);
        }

        public static object Copy(object obj)
        {           
            return DeserializeClass(SerializeClass(obj), obj.GetType());
        }
        #endregion*/

        public static void WriteErrorToLog(Exception objErr,string logname, HttpRequest req,string user)
        {
            string err = //"Error Caught in Application_Error event\n" +
               "User: " + user +
               "\r\nIP: " + req.UserHostAddress +
                   "\r\nError in: " + req.Url.ToString() +
                   "\r\nError Message: " + objErr.Message.ToString() +
                   "\r\nStack Trace:\r\n" + objErr.StackTrace.ToString();
            //EventLog.WriteEntry("Atlas", err, EventLogEntryType.Error);
            //Server.ClearError();

            File.AppendAllText(req.PhysicalApplicationPath + logname, string.Format("Ошибка {0} {1}\r\n{2}\r\n*******************************************\r\n\r\n", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString(), err));//, Encoding.ASCII);

        }

    }
}
